/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-07-08     huan       the first version
 */
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <gpio.h>
#include "key.h"
#include "iis.h"

#define PIN_UP        GET_PIN(C, 5)
#define PIN_DOWN      GET_PIN(C, 1)
#define PIN_LEFT      GET_PIN(C, 0)
#define PIN_RIGHT     GET_PIN(C, 4)

#define BEEP_CONTINUE 100 //beep on 100ms when key press down
#define KEY_DELAY 10 // 10ms 消除抖动

void key_irq_callback(void *args);
void key_real_callback(void *args);
void beep_timer(void *args);
static void delay_10ms(void *args);
static void delay_50ms(void *args);

static rt_timer_t Beep_continue_timer = RT_NULL;
static rt_timer_t Key_delay_timer = RT_NULL;
static rt_timer_t delay_timer_50ms = RT_NULL;
static rt_timer_t delay_timer_10ms = RT_NULL;

static uint32_t pin_num;

Key_HandleTypedef Key_Handle;

extern rt_thread_t Audio_thread;
void key_task(void* parameter)
{

    /* 设置按键中断模式(下降沿触发)与中断回调函数 */
    rt_pin_attach_irq(plug_check, PIN_IRQ_MODE_RISING_FALLING, key_irq_callback, (void *) plug_check);

    /* 使能中断 */
    rt_pin_irq_enable(plug_check, PIN_IRQ_ENABLE);

    Beep_continue_timer = rt_timer_create("Beep_timer", beep_timer, 0, BEEP_CONTINUE, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
    if (Beep_continue_timer != RT_NULL)
    {
        if(rt_timer_start(Beep_continue_timer) == RT_EOK)
            rt_kprintf("Beep_timer is runing!\r\n");
    }

    Key_delay_timer = rt_timer_create("key_timer", key_real_callback, 0, KEY_DELAY, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
    if (Key_delay_timer != RT_NULL)
    {
//        if(rt_timer_start(Key_delay_timer) == RT_EOK)
//            rt_kprintf("key_timer is runing!\r\n");
    }

    delay_timer_50ms = rt_timer_create("delay_50ms", delay_50ms, 0, 50, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
    if (!delay_timer_50ms)
    {
        rt_kprintf("delay_timer_50ms fail to initial \r\n");
    }

    delay_timer_10ms = rt_timer_create("delay_10ms", delay_10ms, 0, 10, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
    if (!delay_timer_10ms)
    {
        rt_kprintf("delay_timer_10ms fail to initial \r\n");
    }

    /* semaphore initailize */
    if (Key_Handle.sem_tx == RT_NULL)
    {
        Key_Handle.sem_tx = rt_sem_create("key_sem_tx", 0, RT_IPC_FLAG_FIFO);
        if (Key_Handle.sem_tx == RT_NULL)
        {
            rt_kprintf("key_sem_tx failed to init!\r\n");
        }
    }
    if (Key_Handle.sem_rx == RT_NULL)
    {
        Key_Handle.sem_rx = rt_sem_create("key_sem_rx", 0, RT_IPC_FLAG_FIFO);
        if (Key_Handle.sem_rx == RT_NULL)
        {
            rt_kprintf("key_sem_rx failed to init!\r\n");
        }
    }

    key_irq_callback(plug_check);

    rt_thread_startup(Audio_thread);
    while (1)
    {
//        rt_kprintf("key running\r\n");
        rt_thread_mdelay(500);
    }
}

void beep_timer(void *args)
{
//    G_ioHandle.toggle(led_2);
}

static void delay_50ms(void *args)
{
    rt_kprintf("delay_50ms===========\r\n\r\n");
    G_ioHandle.high(out_usb3_vbus);
    rt_timer_start(delay_timer_10ms);
}

extern int rt_tas5825_init(void);
static void delay_10ms(void *args)
{
    rt_kprintf("delay_10ms===========\r\n\r\n");
    G_ioHandle.high(out_usb2_vbus);
    /* 配置灯带 */
    G_ioHandle.high(out_audio_power_enable);
    rt_tas5825_init();
    /* 通知播放开机音乐 */
    rt_sem_release(Key_Handle.sem_tx);
//     播放音乐中
    rt_sem_take(Key_Handle.sem_rx, RT_WAITING_FOREVER);

    G_ioHandle.high(out_audio_usb_enable);
    G_ioHandle.low(out_audio_i2s_switch);

//    rt_tas5825_init();
}

enum
{
    plug_out,
    plug_in,
};

static void audio_reset(void)
{
    G_ioHandle.low(out_usb2_reset);
    G_ioHandle.low(out_usb3_reset);
    G_ioHandle.low(out_usb2_vbus);
    G_ioHandle.low(out_usb3_vbus);
    G_ioHandle.low(out_audio_power_enable);
    G_ioHandle.low(out_audio_usb_enable);

}
void key_real_callback(void *args)
{
        rt_timer_start(Beep_continue_timer);
        switch (pin_num)
        {
        case plug_check :
            Key_Handle.state = KEY_UP;
            G_ioHandle.high(out_usb3_reset);
            G_ioHandle.high(out_usb2_reset);
            if (rt_pin_read(plug_check) == plug_in)
            {
                rt_timer_start(delay_timer_50ms);
                rt_kprintf("plug in\r\n");
            }
            else {
                audio_reset();
                rt_kprintf("plug out\r\n");
            }
            break;
        default:
            rt_kprintf("no support pin:%d\r\n", pin_num);
            break;
        }
}

void key_irq_callback(void *args)
{
    pin_num = (uint32_t) args;
    rt_timer_start(Key_delay_timer);
}
